/**
 *******************************************************************************
 * @file  main.c
 * @brief Main program.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2024-08-18       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "main.h"

// 用户引入的系统文件
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <ringbuffer.h>
// 用户引入的芯片库文件

// 用户环境头文件
#include "BspHelper.h"
#include "BufDef.h"
#include "ClkTimerInitHelper.h"
#include "EepromModule.h"
#include "FlashModule.h"
#include "I2cInitHelper.h"
#include "LedBoardModule.h"
#include "NmiHelper.h"
#include "OtsInitHelper.h"
#include "RtcInitHelper.h"
#include "TrngInitHelper.h"
#include "littlefs_port.h"


/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/


/*******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/
bool run_healthy = true;

// 调试串口任务
rt_thread_t debug_usart_tid;
// 串口接收计数监听任务
rt_thread_t usart_transport_check_tid;
// led任务
rt_thread_t led_run_tid;
// rtc任务
rt_thread_t led_rtc_tid;
// 基本数据获取事件
struct rt_event chip_device_event;
rt_thread_t test_data_tid;
// nmi任务
//rt_thread_t nmi_tid;


/*******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/*******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/

/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/


int itoa(int n, char *str, int zero) {
  // 处理数据为0
  if (zero <= 0 && n == 0) {
    str[0] = '0';
    str[1] = '\0';
    return 1;
  } else if (n == 0) {
    int i = 0;
    for (int index = 0; index < zero; index++) {
      str[i++] = '0';
    }
    return i;
  }

  // 处理非零
  // 先处理绝对值部分
  int tmp, i = 0;
  if (n < 0) {
    tmp = -n;
  } else {
    tmp = n;
  }
  // 假设str指向的数组至少有INT_MAX的位数加1个字符的空间
  // 在实际应用中，应该根据具体需求分配足够的空间
  char buf[12];
  do {
    buf[i++] = '0' + tmp % 10;// 取最低位的数字并转换为字符
    tmp /= 10;                // 去掉已经转换的最低位
  } while (tmp > 0);

  if (zero > 0 && i < zero) {
    for (int index = 0; index < zero - i; index++) {
      buf[i++] = '0';
    }
  }
  // 处理负数问题
  if (n < 0) {
    buf[i++] = '-';
  }

  for (int index = 0; index < i; index++) {
    str[index] = buf[i - index - 1];
  }

  str[i] = '\0';// 添加字符串结束符
  return i;
}

// 调试串口发送函数
void Thread_Usart_Send(void *parmameter) {
  for (;;) {
    if (rt_mq_recv(&debug_usart_mq, debug_usart_tx_buf, sizeof(debug_usart_tx_buf), RT_WAITING_FOREVER) > 0) {
      led_status.led_error = 1;
      GPIO_SetPins(LED_RUN_PORT, LED_RUN_PIN);
    }

    {// 控制台DMA发送
      DMA_SetSrcAddr(CM_DMA1, DMA_CH0, (uint32_t) debug_usart_tx_buf);

      DMA_SetTransCount(CM_DMA1, DMA_CH0, rt_strlen(debug_usart_tx_buf));

      (void) DMA_ChCmd(CM_DMA1, DMA_CH0, ENABLE);

      USART_FuncCmd(CM_USART3, USART_TX, ENABLE);
      rt_err_t result = rt_sem_take(debug_usart_sem, 500);
      if (result != RT_EOK) {
        led_status.led_error = 1;
        GPIO_SetPins(LED_RUN_PORT, LED_RUN_PIN);
      }
      rt_thread_yield();
      SWDT_FeedDog();
    }// 控制台DMA发送
  }  // 发送循环
}// 调试串口发送函数

bool init_rtc = false;
uint8_t guid_res[8];
uint8_t eeprom_data_buf[16];
int32_t main_loop(void) {
  rt_thread_mdelay(1000);
  SWDT_FeedDog();
  rt_kprintf("test debug usart t3!\n");
//  if (W25q_Read_Uid(&flash1_obj, guid_res) == RT_EOK) {
//    rt_kprintf("get w25q id: %s\n", guid_res);
//  } else {
//    rt_kprintf("get w25q id error\n");
//  }

//  rt_err_t read_flag = W25q_Read(&flash1_obj, 0x001C00, spi3_rx_build_buf, 1024);
//  if ( read_flag == RT_EOK) {
//    rt_kprintf("read addr 0x%08X: \n", 0x001C00);
//    for (int index = 0; index < 128; index++) {
//      if (index % 32 == 0) {
//        rt_kprintf("256data\n");
//      }
//      rt_kprintf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
//                 spi3_rx_build_buf[0 + 8 * index], spi3_rx_build_buf[1 + 8 * index], spi3_rx_build_buf[2 + 8 * index], spi3_rx_build_buf[3 + 8 * index],
//                 spi3_rx_build_buf[4 + 8 * index], spi3_rx_build_buf[5 + 8 * index], spi3_rx_build_buf[6 + 8 * index], spi3_rx_build_buf[7 + 8 * index]);
//      rt_thread_mdelay(1);
//    }

//  } else if (read_flag == RT_EBUSY){
//    rt_kprintf("read busy\n");
//  } else if (read_flag == RT_EFULL){
//	  rt_kprintf("read resource full\n");
//  } else {
//	  rt_kprintf("read error\n");
//  }

  // 测试I2C读写
  memset(eeprom_data_buf, 0, 16);
  // 填充前半个数组
  Get_Trng_Wait(500);
  rt_kprintf("get trng16: %s\n", trng_str16);
  for (int index = 0; index < 8; index++) {
    eeprom_data_buf[index] = trng_data[index];
  }
  // 填充前后个数组
  Get_Trng_Wait(500);
  rt_kprintf("get trng16: %s\n", trng_str16);
  for (int index = 0; index < 8; index++) {
    eeprom_data_buf[8 + index] = trng_data[index];
  }
  if (Write_Eeprom_Bytes(&eeprom_fram, 0x0000, eeprom_data_buf, 16) == RT_EOK) {
    rt_kprintf("get eeprom 0x%04X data: %02X %02X %02X %02X, %02X %02X %02X %02X, %02X %02X %02X %02X, %02X %02X %02X %02X\n", 0x0000,
               eeprom_data_buf[0], eeprom_data_buf[1], eeprom_data_buf[2], eeprom_data_buf[3],
               eeprom_data_buf[4], eeprom_data_buf[5], eeprom_data_buf[6], eeprom_data_buf[7],
               eeprom_data_buf[8], eeprom_data_buf[9], eeprom_data_buf[10], eeprom_data_buf[11],
               eeprom_data_buf[12], eeprom_data_buf[13], eeprom_data_buf[14], eeprom_data_buf[15]);
  } else {
    rt_kprintf("eeprom read faild\n");
  }

  memset(eeprom_data_buf, 0, 16);
  if (Read_Eeprom_Bytes(&eeprom_fram, 0x0000, eeprom_data_buf, 16) == RT_EOK) {
    rt_kprintf("get eeprom 0x%04X data: %02X %02X %02X %02X, %02X %02X %02X %02X, %02X %02X %02X %02X, %02X %02X %02X %02X\n", 0x0000,
               eeprom_data_buf[0], eeprom_data_buf[1], eeprom_data_buf[2], eeprom_data_buf[3],
               eeprom_data_buf[4], eeprom_data_buf[5], eeprom_data_buf[6], eeprom_data_buf[7],
               eeprom_data_buf[8], eeprom_data_buf[9], eeprom_data_buf[10], eeprom_data_buf[11],
               eeprom_data_buf[12], eeprom_data_buf[13], eeprom_data_buf[14], eeprom_data_buf[15]);
  } else {
    rt_kprintf("eeprom read faild\n");
  }


  //rt_kprintf("get ms: %d\n", ms_cnt);
  //  Get_Trng_Wait(RT_WAITING_FOREVER);
  //  rt_kprintf("get trng by wait: %s\n", trng_str16);
  //  Get_Ots_Wait(RT_WAITING_FOREVER);
  //  rt_kprintf("get ots by wait: %s\n", ots_tmp_str);


  if (!run_healthy) {
    return 1;
  }


  return 0;
}

/**
 * @brief  Main function of the project
 * @param  None
 * @retval int32_t return value, if needed
 */
uint8_t write_buf[4096];
int32_t main(void) {
  if (set_reset == 0xEF) {
    rt_kprintf("set a nmi\n");
  }

  debug_usart_sem = rt_sem_create("debug_usart", 0, RT_IPC_FLAG_PRIO);
  if (debug_usart_sem == RT_NULL) {
    for (;;) {
      led_status.led_error = 1;
      GPIO_SetPins(LED_RUN_PORT, LED_RUN_PIN);
    }
  }
  // 创建用于发送log的锁

  // 初始化log发送线程
  debug_usart_tid = rt_thread_create("Thread_Usart_Send",
                                     Thread_Usart_Send, RT_NULL,
                                     THREAD_STACK_SIZE,
                                     THREAD_PRIORITY, THREAD_TIMESLICE);

  if (debug_usart_tid != RT_NULL) {
    rt_thread_startup(debug_usart_tid);
  }
  SWDT_FeedDog();

  //  // 初始化nmi线程
  //  rt_sem_init(&nmi_sem, "nmt sem", 0, RT_IPC_FLAG_PRIO);
  //  nmi_tid = rt_thread_create("Nmi Task",
  //                             Nmi_Task_Run, RT_NULL,
  //                             THREAD_STACK_SIZE,
  //                             THREAD_PRIORITY, THREAD_TIMESLICE);

  //  if (nmi_tid != RT_NULL) {
  //    rt_thread_startup(nmi_tid);
  //  }
  //  SWDT_FeedDog();

  // 初始化led闪烁线程
  led_run_tid = rt_thread_create("Thread_Led Run",
                                 Thread_Led_Run, RT_NULL,
                                 THREAD_STACK_SIZE,
                                 THREAD_PRIORITY, THREAD_TIMESLICE);
  if (led_run_tid != RT_NULL) {
    rt_thread_startup(led_run_tid);
  }

  // 初始化rtc处理线程
  led_rtc_tid = rt_thread_create("Thread_Rtc Run",
                                 Thread_Rtc_Run, RT_NULL,
                                 THREAD_STACK_SIZE,
                                 THREAD_PRIORITY, THREAD_TIMESLICE);
  if (led_rtc_tid != RT_NULL) {
    rt_thread_startup(led_rtc_tid);
  }

  // 初始化事件集
  if (rt_event_init(&chip_device_event, "chip_device_event", RT_IPC_FLAG_PRIO) != RT_EOK) {
    rt_kprintf("data event init failed!\n");
  }

  // 任务线程初始化结束

  for (int index = 0; index < CONFIG_ARRAY_SIZE; index++) {
    rt_kprintf("get key: %s, value: %s\n", device_address[index].key, device_address[index].value);
    rt_thread_mdelay(1);
  }
  SWDT_FeedDog();


  // 启动毫秒计数器
  ms_cnt = 0;

  // w25q初始化
  //W25q_Init();
  // 初始化LFS
  //Lfs_Init();

  //rt_memset(write_buf, 0xEA, 4096);
//  if (W25q_Erase_1K(&flash1_obj, 0x000000) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Erase_1K(&flash1_obj, 0x000400) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Erase_1K(&flash1_obj, 0x000800) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Erase_1K(&flash1_obj, 0x000C00) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Erase_1K(&flash1_obj, 0x001000) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Erase_1K(&flash1_obj, 0x001400) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Erase_1K(&flash1_obj, 0x001800) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Erase_1K(&flash1_obj, 0x001C00) == RT_EOK) {
//    rt_kprintf("flash1 erase 1K success\n");
//  } else {
//    rt_kprintf("flash1 erase 1K faild\n");
//  }
//  if (W25q_Write_Continuous(&flash1_obj, 0x000000, write_buf, 4096) == RT_EOK) {
//    rt_kprintf("write data success\n");
//  } else {
//    rt_kprintf("write data faild\n");
//  }
//  if (W25q_Write_Continuous(&flash1_obj, 0x001000, write_buf, 4096) == RT_EOK) {
//    rt_kprintf("write data success\n");
//  } else {
//    rt_kprintf("write data faild\n");
//  }
  //lfs_test();


  // 初始化EEPROM
  if (Init_Eeprom() == RT_EOK) {
    rt_kprintf("eeprom init success\n");
  } else {
    rt_kprintf("eeprom init faild\n");
  }


  /* Add your code here */
  int res;
  for (;;) {// 任务主循环
    res = main_loop();
    SWDT_FeedDog();
    rt_thread_yield();
    // 当返回值为正数时为标准退出程序。直接退出。为0时啥也不干。为负时有错且需要出发处理程序
    if (res > 0) {
      break;
    } else if (res < 0) {
      ;
    } else {
      ;
    }// min_loop返回值处理
  }  // 任务主循环
}

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
